package edu.siu.math.egut.util;

import java.io.IOException;
import java.io.Serializable;

import edu.siu.math.egut.io.BadLiECommandException;
import edu.siu.math.egut.io.Constants;
import edu.siu.math.egut.io.LiE;
import edu.siu.math.egut.io.OutputPref;
import edu.siu.math.egut.main.OutputStyle;

/**
 * @author josephhundley
 * 
 */
public class WeylWord implements Serializable {
    public Group getG() {
	return g;
    }

    public void setG(Group g) {
	this.g = g;
    }

    public int[] getWord() {
	return word;
    }

    public void setWord(int[] word) {
	this.word = word;
    }

    public static long getSerialversionuid() {
	return serialVersionUID;
    }

    /**
     * 
     */
    private static final long serialVersionUID = 1003078377161384937L;
    private Group g;
    private int[] word;

    public WeylWord(int[] w, Group g1) {
	g = g1;
	word = checkDigits(w, g.getRank());

    }

    private int[] checkDigits(int[] w, int rank) {
	for (int i = 0; i < w.length; i++) {
	    if (w[i] < 1 || w[i] > rank) {
		System.out
			.println("Attempt to initialize Weyl element with bad data.");
		System.exit(1);
	    }

	}

	return w;
    }

    WeylWord(String s, Group g1) {
	g = g1;
	word = readAndCheckDigits(s, g.getRank());
    }

    private int[] readAndCheckDigits(String s, int rank) {
	int[] result = new int[s.length()];
	for (int i = 0; i < s.length(); i++) {
	    int d = edu.siu.math.egut.io.Algorithms.value(s.charAt(i));
	    if (d < 1 || d > rank) {
		System.out
			.println("Attempt to initialize Weyl element with bad data.");
		System.exit(1);
	    }
	    result[i] = d;

	}

	return result;
    }

    public static WeylWord read(String string, Group g)
	    throws WeylWordReadException {
	string = edu.siu.math.egut.io.Algorithms.removeWhiteSpaceCommasAndBrackets(string);
	if (!Algorithms.representsWeylWord(string, g.getRank()))
	    throw new WeylWordReadException();
	if (string.matches(""))
	    return new WeylWord(new int[0], g);

	return new WeylWord(edu.siu.math.egut.io.Algorithms
		.tupleFromString(string), g);
    }

    public String toString(OutputStyle sty) {

	switch (sty) {
	case TEX:
	    String raw = "w["
		    + edu.siu.math.egut.io.Algorithms.tupleToShortString(word)
		    + "]";
	    if (raw.length() < Constants.SCREEN_WIDTH)
		return raw;
	    else {
		StringBuilder sb = new StringBuilder("\\begin{array}{r}w[");
		int width = 2;
		for (int i = 0; i < word.length; i++) {
		    if (width >= Constants.SCREEN_WIDTH) {
			sb.append("\\\\\n");
			width = 3;

		    }
		    sb.append(Integer.toString(word[i]));
		}
		sb.append("]\\end{array}");
		return sb.toString();
	    }
	case LIE:
	    return edu.siu.math.egut.io.Algorithms.tupleToString(word);
	case SCREEN:
	    return edu.siu.math.egut.io.Algorithms.tupleToShortString(word);

	}
	return edu.siu.math.egut.io.Algorithms.tupleToString(word);

    }

    public static WeylWord parse(String input, Group g) {
	if (!Algorithms.representsWeylWord(input, g.getRank()))
	    return null;

	return new WeylWord(edu.siu.math.egut.io.Algorithms
		.tupleFromString(input), g);
    }

    public static WeylWord reduceByInverse(WeylWord w, WeylWord w1, Group g1, OutputPref op)
	    throws WeylWordReadException, IOException, BadLiECommandException {
	LiE lie = new LiE();
	return WeylWord.read(edu.siu.math.egut.io.Algorithms
		.removeWhiteSpaceCommasAndBrackets(lie.exec("reduce("
			+ w.toString(OutputStyle.LIE) + "^inverse("
			+ w1.toString(OutputStyle.LIE) + ")," + g1.toString()
			+ ")", op)), g1);
    }

//    public static WeylWord reduceByInverse(WeylWord w, WeylWord w1, Group g1)
//    throws WeylWordReadException, IOException, BadLiECommandException {
//LiE lie = new LiE();
//return WeylWord.read(edu.siu.math.egut.io.Algorithms
//	.removeWhiteSpaceCommasAndBrackets(lie.exec("reduce("
//		+ w.toString(OutputStyle.LIE) + "^inverse("
//		+ w1.toString(OutputStyle.LIE) + ")," + g1.toString()
//		+ ")", OutputPref.HIDE)), g1);
//}




}
